import queue
import threading
from pydub import AudioSegment
from .chattts import text_to_speech, get_random_speaker, clean_temp_folder


class AudioProcessor:
    def __init__(self, messages):
        self.audio_queue = queue.Queue()
        self.messages = messages
        chunks = self.split_into_chunks(self.messages)
        self.random_speaker = get_random_speaker()
        self.audio_count = 0
        self.generate_audio(chunks)
        clean_temp_folder()

    @staticmethod
    def replace_percent(text):
        """将数字和百分比转换为中文表述"""
        import re

        def number_to_chinese(num_str):
            """将阿拉伯数字字符串转换为中文数字"""
            num_map = {'0': '零', '1': '一', '2': '二', '3': '三',
                       '4': '四', '5': '五', '6': '六',
                       '7': '七', '8': '八', '9': '九'}
            unit_map = {1: '', 2: '十', 3: '百', 4: '千', 5: '万'}

            # 分离整数和小数部分
            if '.' in num_str:
                integer_part, decimal_part = num_str.split('.')
            else:
                integer_part, decimal_part = num_str, ''

            # 处理整数部分
            result = []
            for i, char in enumerate(integer_part):
                # 处理连续零的情况（保留单位）
                if char == '0' and (i == 0 or integer_part[i - 1] == '0'):
                    continue
                result.append(num_map[char])
                # 添加单位（千、百、十）
                position = len(integer_part) - i
                if position > 1 and char != '0':
                    result.append(unit_map.get(position, ''))

            # 处理小数部分
            if decimal_part:
                result.append('点')
                for char in decimal_part:
                    result.append(num_map[char])

            # 处理特殊情况（一十 -> 十）
            chinese_num = ''.join(result).replace('零零', '零').rstrip('零')
            if chinese_num.startswith('一十'):
                chinese_num = chinese_num[1:]
            return chinese_num or '零'

            # 新增年份专用转换函数
        def number_to_chinese_year(num_str):
            """将年份数字逐位转换"""
            num_map = {'0': '〇', '1': '一', '2': '二', '3': '三', '4': '四',
                        '5': '五', '6': '六', '7': '七', '8': '八', '9': '九'}
            return ''.join(num_map[char] for char in num_str if char in num_map)

        # 匹配所有数字（包括小数）及可能的后缀单位
        pattern = r'(\d+\.?\d*)(%|年|月|日|人|元|美元|°C|℃|米|吨|千克|公里|时|分|秒|磅)?'

        def repl(match):
            num = match.group(1)
            unit = match.group(2) or ''

            # 特殊处理年份
            if unit == '年':
                return f'{number_to_chinese_year(num)}{unit}'

            chinese_num = number_to_chinese(num)
            if unit == '%':
                return f'百分之{chinese_num}'
            return f'{chinese_num}{unit}'

        return re.sub(pattern, repl, text)

    def split_into_chunks(self, text, min_length=50):
        """智能分句函数，保留标点完整性"""
        text = self.replace_percent(text)
        import re
        pattern = r'(?<=[！。？!?])'
        sentences = re.split(pattern, text)
        chunks = []
        current_chunk = []

        for seg in sentences:
            seg = seg.strip()
            if not seg:
                continue

            current_chunk.append(seg)
            # 合并过短的句子（最小长度控制）
            if sum(len(s) for s in current_chunk) >= min_length:
                chunks.append(''.join(current_chunk))
                current_chunk = []

        # 添加剩余内容
        if current_chunk:
            chunks.append(''.join(current_chunk))

        return chunks

    def generate_audio(self, chunks):
        """启动音频生成线程"""
        self.audio_count += len(chunks)
        threading.Thread(
            target=self._generate_audio_worker,
            args=(chunks,)
        ).start()

    def _generate_audio_worker(self, chunks):
        """实际处理音频生成的线程函数"""
        for index, text in enumerate(chunks):
            audio_path = text_to_speech(text, rand_spk=self.random_speaker)
            self.audio_queue.put([index, audio_path, text])

    def get_audio(self, timeout=3):
        """从队列获取音频数据"""
        try:
            audio_info = self.audio_queue.get(timeout=timeout)
            audio = AudioSegment.from_wav(audio_info[1])
            duration = len(audio) / 1000
            self.audio_count -= 1
            return audio_info, duration-0.05
        except queue.Empty:
            return None, 0
